<template>
	<!-- 根节点 -->
	<view class="device-status-page">
		<!-- 蓝牙 -->
		<view class="upage__item">
			<view class="" @click="backFn">
				<u-icon name="arrow-left" color="#424242" size="20"></u-icon>
			</view>
			<view class="" style="font-size: 35rpx;color: #0a0f12;">
				配置XGM模块
			</view>
			<view class="" style="width: 240rpx;" @click="butBleFn">
				<u-button type="primary" shape="circle" :color="butcolor" :text="rightText"></u-button>
			</view>
		</view>
		<!-- 北斗状态卡片 -->
		<view class="status-card">
			<view class="status-title">
				<view class="">
					① 北斗搜索状态
				</view>
				<view class="">
					<view class="status-indicator"
						:class="{ success: bdCompleted && bdCompIF, fail: !bdCompleted && bdCompIF }">
						{{ bdCompIF ? '搜索完成' : '进行中...' }}
					</view>
				</view>
			</view>
			<!-- 状态文字和状态区域同一行 -->
			<view class="status-text">{{ bdStatusText }}</view>
		</view>

		<!-- XGM 状态卡片 -->
		<view class="status-card">
			<view class="status-title">
				<view class="">
					② XGM 模块搜索状态
				</view>
				<view class="">
					<view class="status-indicator"
						:class="{ success: xgmCompleted && xgmCompIF, fail: !xgmCompleted && xgmCompIF }">
						{{ xgmCompIF? '搜索完成' : '进行中...' }}
					</view>
				</view>
			</view>
			<view class="status-text">{{ xgmStatusText }}</view>
		</view>
		<!-- 配置状态卡片 -->
		<view class="status-card">
			<view class="status-title">
				<view class="">
					③ XGM模块配置状态
				</view>
				<view class="">
					<!-- <view class="workkip" :class="{disacss: !skipIF}" @click="skipStep('config')">配置完成</view> -->
					<view class="workkip" @click="skipStep('config')">配置完成</view>
				</view>
			</view>
			<view class="status-text">{{ configStatusText }}</view>
		</view>
		<!-- 命令发送区 -->
		<view class="command-card">
			<view class="command-title">📡 发送命令到 XGM 模块</view>
			<view class="command-hint">可输入配置指令，例如：</view>
			<view class="command-sample">
				admin,socket2,1,net,tcp,112.125.89.8,46803,long,5,60,tcp,off,off,off,off
			</view>
			<!-- 输入框 -->
			<view class="input-box">
				<textarea v-model="commandText" placeholder="请输入要发送的命令..."></textarea>
			</view>
			<!-- 发送/清空按钮 -->
			<view class="btn-group">
				<u-button type="primary" text="发送命令" @click="sendCommand"></u-button>
			</view>
		</view>
		<!-- 工作参数配置 -->
		<view class="status-card">
			<view class="status-title">
				<view class="">
					④ 工作参数配置状态
				</view>
				<view class="">
					<!-- <view class="workkip"  @click="skipStep('work')">前往配置</view> -->
					<view class="workkip" @click="skipStep('configurationCompleted')">
						配置完成</view>
<!-- 					<view class="workkip" :class="{disacss: !configuIF}" @click="skipStep('configurationCompleted')">
						配置完成</view> -->
				</view>
			</view>
			<view class="status-title">
				<view class="status-text">{{ jobConfiguration }}</view>
				<view class="" style="display: flex;justify-content: space-between;align-items: center;">
					<!-- <view class="workkip" :class="{disacss: !configuIF}" @click="skipStep('time')">配置时间</view>
					<view class="workkip" style="margin-right: 20rpx;" :class="{disacss: !configuIF}" @click="skipStep('work')">配置参数</view> -->
					<view class="workkip"  @click="skipStep('time')">配置时间</view>
					<view class="workkip" style="margin-left: 20rpx;" @click="skipStep('work')">配置参数</view>
					
				</view>
			</view>
		</view>
		<!-- 命令发送区 -->
		<view class="command-card">
			<!-- 最近发送命令显示 -->
			<view class="send-log" v-if="sentLogs.length">
				<view class="send-title">最近接收：</view>
				<view v-for="(item, index) in sentLogs" :key="index" class="send-item">
					<view class="send-content">{{ item }}</view>
					<view class="btn-copy" @click="copyCommand(item)">复制</view>
				</view>
				<u-button color="#8b8b8b" @click="clearCommand" text="清空"></u-button>
			</view>
		</view>
		
		<u-button style="margin: 20rpx 0;" @click="testRestartFn" type="error" shape="circle" text="重启设备"></u-button>
		<!-- 		<u-button style="margin: 20rpx 0;" @click="testObtainRainfallFn" type="error" shape="circle"
			text="获取雨量"></u-button> -->
	</view>
</template>

<script>
	import {
		hexToString,
		extractMainStatus,
		strToHexArray
	} from '@/common/hexUtils.js'; // 根据你的目录修改路径
	export default {
		data() {
			return {
				deviceId: '', //蓝牙
				serviceId: '', //蓝牙
				characteristicId: '', //蓝牙
				fff: '', //蓝牙
				butcolor: '#f43f3f',
				rightText: '连接设备',
				// 英文消息
				configMessage: "",

				// 中文状态显示
				bdStatusText: "正在搜索北斗...",
				xgmStatusText: "等待北斗完成后开始搜索 XGM 模块...",
				configStatusText: "等待配置开始...",
				jobConfiguration: "等待配置开始...", //工作配置

				// 每步是否完成
				bdCompleted: false,
				xgmCompleted: false,

				// 命令输入框
				commandText: "",
				sentLogs: [], // 改为数组存储历史命令
				// 状态
				bdCompIF: false, //北斗
				xgmCompIF: false, //4G
				skipIF: false, //跳过
				configuIF: false //配置
			};
		},
		onUnload() {
			console.log('卸载');
		},
		onShow() {
			uni.showLoading({
				title: '加载中',
				mask: true
			});
			setTimeout(() => {
				uni.hideLoading();
			}, 3000);

			this.bdCompIF = false //北斗
			this.xgmCompIF = false //4G
			this.skipIF = false //跳过
			this.configuIF = false //配置
			this.bdCompleted = false //北斗
			this.xgmCompleted = false //4G
			// 断开设备
			uni.onBLEConnectionStateChange((res) => {
				// 该方法回调中可以用于处理连接意外断开等异常情况
				if (res.connected !== true) {
					this.butcolor = '#be3131'
					this.rightText = '连接设备'
					uni.$u.vuex('vuex_devicename', '')
					uni.$u.vuex('vuex_deviceId', '')
					uni.navigateBack({
						delta: 1
					});
				}
			})

			this.deviceId = this.vuex_deviceId
			this.getBLEDeviceServices()
		},
		onLoad() {

		},
		methods: {
			// 重启
			testRestartFn() {
				let msg = ['0x52', '0x45', '0x53', '0x45', '0x54', '0x0D', '0x0A']
				this.conbuffer(msg)
			},
			// 获取雨量
			testObtainRainfallFn() {
				let msg = ['0x48']
				this.conbuffer(msg)
			},
			/**
			 * 处理蓝牙收到的消息
			 * @param {String} rawMsg 原始消息
			 */
			onBluetoothMessage(rawMsg) {
				const msgClean = rawMsg

				console.log("接收到消息:", msgClean);

				// ===== 北斗状态 =====
				if (msgClean == "seekingbd...") {
					this.bdStatusText = "正在搜索北斗...";
				} else if (msgClean == "bdisfound!") {
					this.bdStatusText = "✅ 北斗已搜索到";
					this.bdCompleted = true;
					this.bdCompIF = true;
				} else if (msgClean == "bdisnotfound!") {
					this.bdStatusText = "❌ 北斗未搜索到";
					this.bdCompleted = false;
					this.bdCompIF = true;
				}

				// ===== XGM 状态 =====
				else if (msgClean == "seekingxgm...") {
					this.xgmStatusText = "正在搜索 XGM 模块...";
				} else if (msgClean == "xgmisfound!") {
					this.xgmStatusText = "✅ XGM 模块已找到";
					this.xgmCompleted = true;
					this.xgmCompIF = true;
				} else if (msgClean == "xgmisnotfound!") {
					this.xgmStatusText = "❌ 未找到 XGM 模块";
					this.xgmCompleted = false;
					this.xgmCompIF = true;
				}

				// ===== 配置阶段 =====
				else if (msgClean == "configurationxgmstarts!") {
					this.configStatusText = "等待手机 APP 对 XGM 模块进行配置...";
					this.skipIF = true;
				} else if (msgClean == "configurationxgmends!") {
					this.configStatusText = "XGM 模块配置结束";

				} else if (msgClean == "configuratioinparameterstarts!") {
					// 工作参数配置
					this.jobConfiguration = '工作参数可配置';
					this.configuIF = true
				}
			},

			/**
			 * 跳过步骤
			 * @param {String} step 步骤名称 'bd' | 'xgm' | 'config'
			 */
			skipStep(step) {
				if (step == "config" && this.xgmCompleted) {
					let msg = ['0x45', '0x58', '0x49', '0x54', '0x31', '0x0D', '0x0A']
					this.conbuffer(msg)
					console.log('配置4G');
				} else if (step == "work") {
					uni.navigateTo({
						url: '/pages/index/setUp'
					});
					console.log('工作参数');
				} else if (step == 'configurationCompleted') {
					let msg = ['0x45', '0x58', '0x49', '0x54', '0x32', '0x0D', '0x0A']
					this.conbuffer(msg)
				} else if (step == 'time') {
					uni.navigateTo({
						url: '/pages/index/configurationTime'
					});
					console.log('配置时间');
				}
			},
			/**
			 * 模拟发送命令
			 */
			sendCommand() {
				if (!this.commandText.trim()) {
					uni.showToast({
						title: "请输入命令",
						icon: "none"
					});
					return;
				}
				let msg = strToHexArray(this.commandText)
				this.conbuffer(msg)

				console.log('发送', msg);
			},
			acceptXgmFn(data) {
				if (this.hexToCleanString(data) == 'mobileappisstillactive!') {
					this.configuIF = false
				}
				let str = hexToString(data)
				console.log('str', str);
				// 添加到历史记录数组前面
				this.sentLogs.unshift(str);

				// 控制最多显示20条记录（可选）
				if (this.sentLogs.length > 10) {
					this.sentLogs.pop();
				}
			},
			// 复制
			copyCommand(cmd) {
				uni.setClipboardData({
					data: cmd,
					success: () => {
						uni.showToast({
							title: "已复制",
							icon: "success"
						});
					}
				});
			},
			// 清空
			clearCommand() {
				this.sentLogs = [];
			},
			//监听消息变化-----------------------------------------------------
			listenValueChange() {
				setTimeout(() => {
					uni.onBLECharacteristicValueChange(res => {
						let resHex = this.ab2hex(res.value)
						console.log('监听初始化数据', resHex, resHex.length);
						//模块状态
						this.handleBluetoothHex(resHex)
						//接受XGM返回
						this.acceptXgmFn(resHex)

					})
				}, 300)
			},
			// 删除多余的数字横杠
			hexToCleanString(hexStr) {
				// 1️⃣ 清理输入：去空格并转小写
				hexStr = hexStr.replace(/\s+/g, '').toLowerCase();

				// 2️⃣ 转成普通字符串
				let text = '';
				for (let i = 0; i < hexStr.length; i += 2) {
					const byte = parseInt(hexStr.substr(i, 2), 16);
					if (!isNaN(byte)) text += String.fromCharCode(byte);
				}

				// 3️⃣ 去掉前缀“数字+---”部分
				text = text.replace(/^\d+\-\-\-/, '');

				// 4️⃣ 去掉换行、空格，转小写
				text = text.replace(/[\r\n\s]+/g, '').toLowerCase();

				return text;
			},
			backFn() {
				uni.navigateBack({
					delta: 1
				});
			},
			butBleFn() {
				if (this.rightText == '设备已连接') {
					this.duankai()
				} else {
					uni.navigateTo({
						url: '/pages/index/BLE'
					});
				}
			},
			duankai() {
				uni.closeBLEConnection({
					deviceId: this.vuex_deviceId,
					success: (res) => {
						this.lanname = ''
						uni.$u.vuex('vuex_devicename', '')
						uni.$u.vuex('vuex_deviceId', '')
						this.butcolor = '#be3131'
						this.rightText = '连接设备'
					}
				})

			},
			/**
			 * 处理蓝牙收到的16进制字符串，拆分成多条消息，并逐条处理
			 * @param {String} hexStr 蓝牙接收到的16进制字符串
			 */
			/**
			 * 处理蓝牙接收的16进制字符串，拆分多条消息
			 * @param {String} hexStr 16进制字符串
			 */
			handleBluetoothHex(hexStr) {
				// 1. 把 16 进制转成字符串，忽略 0x00
				let str = '';
				for (let i = 0; i < hexStr.length; i += 2) {
					const hexCode = hexStr.substr(i, 2);
					if (hexCode !== '00') { // 忽略填充的 0x00
						str += String.fromCharCode(parseInt(hexCode, 16));
					}
				}

				// 2. 按回车换行拆分成数组
				let messages = str.split(/\r?\n/).filter(item => item); // 去掉空字符串

				// 3. 遍历每条消息，去掉空格并转小写
				messages.forEach(msg => {
					const cleaned = msg.replace(/\s+/g, '').toLowerCase();
					// console.log('处理消息:', cleaned); // 可以改成调用你原来的 onBluetoothMessage(cleaned)
					this.onBluetoothMessage(cleaned); // 注意这里传原始可读消息，便于显示
				});
			},
			/**
			 * 去掉数组中每个字符串的所有空格，并转为小写
			 * @param {string[]} arr 原始字符串数组
			 * @returns {string[]} 处理后的新数组
			 */
			normalizeStrings(arr) {
				if (!Array.isArray(arr)) return [];
				return arr.map(s => String(s).replace(/\s+/g, '').toLowerCase());
			},
			// ArrayBuffer转16进度字符串示例
			ab2hex(buffer) {
				const hexArr = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return ('00' + bit.toString(16)).slice(-2)
					}
				)
				return hexArr.join('')
			},
			// 输入蓝牙数据
			conbuffer(data) {
				let msg = data
				// 向蓝牙设备发送一个0x00的16进制数据
				const buffer = new ArrayBuffer(msg.length)
				const dataView = new DataView(buffer)
				// dataView.setUint8(0, 0)
				for (var i = 0; i < msg.length; i++) {
					// dataView.setUint8(i, msg.charAt(i).charCodeAt())
					dataView.setUint8(i, msg[i]);
				}
				this.sendMsgToKey(buffer)
			},
			/* 向设备发送消息(分包发送，单包20字节，递归发送)
			 */
			sendMsgToKey(buffer) {
				// console.log('buffer', buffer);
				var that = this //vue中的this
				const packageSize = 20 //分包大小
				if (buffer.byteLength <= 20) { //如果小于20直接发送，不再继续调用
					uni.writeBLECharacteristicValue({
						// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
						deviceId: that.deviceId,
						// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
						serviceId: that.serviceId,
						// 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
						characteristicId: that.fff, //第二步写入的特征值
						// 这里的value是ArrayBuffer类型
						value: buffer,
						writeType: 'write',
						success: (res) => {
							//此时设备已接收到你写入的数据
							console.log('写入111');

						},
						fail: (err) => {
							console.log('传输失败', err)
						},
						complete: function() {}
					})
				} else { //如果大于20发送完成后继续递归调用
					var newData = buffer.slice(20)
					var writeBuffer = buffer.slice(0, 20)
					uni.writeBLECharacteristicValue({
						// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
						deviceId: that.deviceId,
						// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
						serviceId: that.serviceId,
						// 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
						characteristicId: that.fff, //第二步写入的特征值
						// 这里的value是ArrayBuffer类型
						value: writeBuffer,
						writeType: 'write',
						success: function(res) {
							console.log('写入222');
							//写入后继续递归调用发送剩下的数据
							setTimeout(() => {
								that.sendMsgToKey(newData)
							}, 100)
						},
						fail: (err) => {
							console.log('传输失败', err)
						},
						complete: function() {}
					})
				}
			},
			//获取蓝牙的所有服务
			getBLEDeviceServices() {
				setTimeout(() => {
					uni.getBLEDeviceServices({
						// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
						deviceId: this.vuex_deviceId,
						success: (res) => {
							console.log('获取蓝牙所有服务', res);
							//E95D93AF-251D-470A-A062-FA1922DFA9A8
							//6E400001-B5A3-F393-E0A9-E50E24DCCA9E
							res.services.forEach((item) => {

								if (item.uuid.indexOf("0000FFF0") != -1) {
									this.serviceId = item.uuid;

									//获取特征
									this.getBLEDeviceCharacteristics()
								}
								if (item.uuid.indexOf("0000FFE0") != -1) {
									this.serviceId = item.uuid;

									//获取特征
									this.getBLEDeviceCharacteristics()
								}
							})
						}
					})
				}, 1000)
			},
			//获取蓝牙特征
			getBLEDeviceCharacteristics() {
				console.log('获取蓝牙特征值');
				setTimeout(() => {
					uni.getBLEDeviceCharacteristics({
						// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
						deviceId: this.deviceId,
						// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
						serviceId: this.serviceId,
						success: (res) => {

							this.characteristics = res.characteristics
							res.characteristics.forEach((item) => {

								if (item.uuid.indexOf("FFF2") != -1) {
									this.fff = item.uuid

								}
								if (item.uuid.indexOf("FFE1") != -1) {
									this.fff = item.uuid

								}
								if (item.uuid.indexOf("0000FFE1") != -1) {

									this.characteristicId = item.uuid
									//利用传参的形势传给下面的notify，这里的uuid如果都需要用到，就不用做判断了，建议使用setTimeout进行间隔性的调用此方法
									this.notifyBLECharacteristicValueChange(item.uuid)
								}
								if (item.uuid.indexOf("0000FFF1") != -1) {

									this.characteristicId = item.uuid


									//利用传参的形势传给下面的notify，这里的uuid如果都需要用到，就不用做判断了，建议使用setTimeout进行间隔性的调用此方法
									this.notifyBLECharacteristicValueChange(item.uuid)
								}
							})
						},
						fail: (res) => {
							console.log(res)
						}
					})
				}, 1000)
			},
			// 启用 notify 功能
			notifyBLECharacteristicValueChange(characteristicId) {
				console.log('启用 notify 功能');
				uni.notifyBLECharacteristicValueChange({
					state: true, // 启用 notify 功能
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: this.deviceId,

					// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
					serviceId: this.serviceId,
					// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
					characteristicId: this.characteristicId,
					success: (res) => {
						console.log('蓝牙名字', res);
						// vuex
						// uni.$u.vuex('vuex_devicename', this.vuexlist.name)
						uni.hideLoading()
						this.listenValueChange()
						// uni.showToast({
						// 	title: '服务已开启',
						// 	icon: 'success',
						// 	mask: true,
						// 	duration: 1000
						// });
						// uni.hideToast();
						this.butcolor = '#00aa7f'
						this.rightText = '设备已连接'
						// uni.showToast({
						// 	title: '信息获取中...',
						// 	icon: 'loading',
						// 	mask: true,
						// 	duration: 10000
						// });
					},
					fail: (res) => {
						uni.hideLoading()
						uni.showToast({
							title: '获取服务失败',
							icon: 'fail',
							mask: true,
							duration: 1000
						});

					}
				})

			},
		}
	};
</script>

<style lang="scss">
	.upage__item {
		margin-top: 80rpx;
		padding: 0 30rpx 30rpx 30rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
	}

	.device-status-page {
		padding: 30rpx;
		// background-color: #f8f9fb;
		color: #333;
		// min-height: 90vh;

		/* 页面标题 */
		.title {
			font-size: 40rpx;
			font-weight: bold;
			text-align: center;
			margin-bottom: 40rpx;
		}

		/* 状态卡片 */
		.status-card {
			background: #fff;
			border-radius: 20rpx;
			padding: 25rpx;
			margin-bottom: 10rpx;
			box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);

			.status-title {
				display: flex;
				justify-content: space-between;
				align-items: center;
				font-size: 30rpx;
				font-weight: bold;
				margin-bottom: 10rpx;

				.workkip {
					padding: 20rpx;
					border-radius: 10rpx;
					font-size: 28rpx;
					text-align: center;
					color: #fff;
					background: #2b7cff;

					&:active {
						background-color: #1c52a8;
					}
				}

				.disacss {
					pointer-events: none;
					background-color: #c7c7c7;

				}
			}

			/* 状态 + 跳过按钮一行显示 */
			.status-text {
				font-size: 32rpx;
				color: #2b7cff;
				font-weight: 600;
			}

			.english-text {
				font-size: 26rpx;
				color: #888;
			}

			.disabled {
				background: #ccb929;
			}
		}

		/* 命令发送区 */
		.command-card {
			background: #fff;
			border-radius: 20rpx;
			padding: 25rpx;
			box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.05);
			margin-bottom: 30rpx;

			.command-title {
				font-size: 32rpx;
				font-weight: bold;
				margin-bottom: 10rpx;
				color: #2b7cff;
			}

			.command-hint {
				font-size: 26rpx;
				color: #666;
				margin-bottom: 6rpx;
			}

			.command-sample {
				font-size: 24rpx;
				color: #c7254e;
				background: #f9f2f4;
				padding: 6rpx 10rpx;
				border-radius: 8rpx;
				font-family: monospace;
				margin-bottom: 20rpx;
				word-break: break-all;
			}

			.input-box {
				background: #f6f7fb;
				border-radius: 10rpx;
				padding: 10rpx;
				margin-bottom: 20rpx;

				textarea {
					width: 100%;
					min-height: 120rpx;
					font-size: 26rpx;
					color: #333;
					border: none;
					resize: none;
				}
			}

			.btn-group {
				display: flex;
				justify-content: space-between;
				margin-bottom: 15rpx;

				.send {
					background: #2b7cff;
				}

				.clear {
					background: #999;
				}
			}

			.send-log {
				font-size: 26rpx;
				color: #555;
				word-break: break-all;

				.send-title {
					font-weight: bold;
					margin-bottom: 4rpx;
				}

				.send-content {
					background: #f9f9f9;
					padding: 10rpx;
					border-radius: 10rpx;
					font-family: monospace;
					color: #333;
				}

				.send-item {
					display: flex;
					align-items: center;
					margin-bottom: 10rpx;

					.send-content {
						flex: 1;
						background: #f9f9f9;
						padding: 10rpx;
						border-radius: 10rpx;
						font-family: monospace;
						color: #333;
						word-break: break-all;
					}

					.btn-copy {
						margin-left: 10rpx;
						padding: 8rpx 12rpx;
						background: #2b7cff;
						color: #fff;
						font-size: 24rpx;
						border-radius: 8rpx;
						text-align: center;
					}
				}

			}
		}

		.status-indicator {
			padding: 8rpx 15rpx;
			border-radius: 10rpx;
			font-size: 20rpx;
			color: #fff;
			background: #c7c7c7; // 默认灰
			text-align: center;

			&.success {
				background: #00aa7f; // 成功绿
			}

			&.fail {
				background: #e54d42; // 失败红
			}
		}

	}
</style>
<style>
	page {
		background-color: #f2f1f6;
	}
</style>